/* $URL$
   $Rev$
   $Author$
   $Date$
   $Id$
 */

#include "vgl.h"
#include <vermilion.h>
#include "vapp.h"
#include "vutils.h"
#include "vbm.h"
#include "LoadShaders.h"
#include "vmath.h"
#include <stdio.h>

BEGIN_APP_DECLARATION(VolumeTextureExample)
// Override functions from base class
virtual void Initialize(const char* title);
virtual void Display(bool auto_redraw);
virtual void Finalize(void);
virtual void Reshape(int width, int height);

// Member variables
float aspect;
GLuint base_prog;
GLuint vao;

GLuint quad_vbo;

GLuint tex;
END_APP_DECLARATION()

DEFINE_APP(VolumeTextureExample, "Volume Texture Example")

void VolumeTextureExample::Initialize(const char* title)
{
	base::Initialize(title);

	ShaderInfo quad_shaders[] = { 
		{ GL_VERTEX_SHADER,   "volume_texture.vs.glsl" }, 
		{ GL_FRAGMENT_SHADER, "volume_texture.fs.glsl" },
		{ GL_NONE, NULL } 
	};
	base_prog = LoadShaders(quad_shaders);

	glGenBuffers(1, &quad_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, quad_vbo);

	static const GLfloat quad_data[] =
	{
		// position
		 1.0f, -1.0f,
		-1.0f, -1.0f,
		-1.0f, 1.0f,
		 1.0f, 1.0f,
		 // tex_coord
		 0.0f, 0.0f,
		 1.0f, 0.0f,
		 1.0f, 1.0f,
		 0.0f, 1.0f
	};

	glBufferData(GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW);

	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(8 * sizeof(float)));

	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	vglImageData image;

	tex = vglLoadTexture("../../../media/cloud.dds", 0, &image);

	glTexParameteri(image.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	vglUnloadImage(&image);
}

void VolumeTextureExample::Display(bool auto_redraw)
{
	static const unsigned int start_time = GetTickCount();
	float t = float((GetTickCount() - start_time)) / float(0x3FFF);
	static const vmath::vec3 X(1.0f, 0.0f, 0.0f);
	static const vmath::vec3 Y(0.0f, 1.0f, 0.0f);
	static const vmath::vec3 Z(0.0f, 0.0f, 1.0f);

	vmath::mat4 tc_matrix(vmath::mat4::identity());

	glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
	glClearDepth(1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glDisable(GL_CULL_FACE);
	glUseProgram(base_prog);

	tc_matrix = vmath::rotate(t * 170.0f, X) 
				* vmath::rotate(t * 137.0f, Y) 
				* vmath::rotate(t * 93.0f, Z);

	glUniformMatrix4fv(glGetUniformLocation(base_prog, "tc_rotate"), 1, GL_FALSE, tc_matrix);
	glBindVertexArray(vao);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	base::Display();
}

void VolumeTextureExample::Finalize(void)
{
	glUseProgram(0);
	glDeleteProgram(base_prog);
	glDeleteTextures(1, &tex);
	glDeleteVertexArrays(1, &tex);
}

void VolumeTextureExample::Reshape(int width, int height)
{
	glViewport(0, 0, width, height);

	aspect = float(height) / float(width);
}
